/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Id: CLUtils.java 658 2007-06-30 08:59:11Z jack.rybicki $
 */
package gammu.java.machines;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Command line utilities.
 * 
 */
public class CLUtils {

	/**
	 * 
	 * Execute an external command.
	 * 
	 * @param params
	 *            program name and all necessary parameters.
	 * @return started process.
	 * @throws RuntimeException
	 *             if unable to execute command.
	 */
	public static Process execute(String... params) {
		try {
			return new ProcessBuilder(params).start();
		} catch (IOException e) {
			throw new RuntimeException("Unable to execute command: "
					+ Arrays.toString(params), e);
		}

	}

	/**
	 * 
	 * Read lines from process output.
	 * 
	 * @param stream
	 *            process output stream.
	 * @param terminatingPattern
	 *            reading is stopped after the pattern is found. The result
	 *            include the last line read from input.
	 * @param limit
	 *            limit of lines to read.
	 * @return list of Strings not containing pattern, list not longer than
	 *         specified limit.
	 * @throws IOException
	 *             if any IO error occurs.
	 */
	public static List<String> readLines(InputStream stream,
			String terminatingPattern, int limit) throws IOException {

		Pattern pattern=null;
		if (terminatingPattern != null) {
			pattern = Pattern.compile(terminatingPattern);
		}
		BufferedReader br = new BufferedReader(new InputStreamReader(stream));
		List<String> result = new ArrayList<String>(3);
		String line = br.readLine();
		while ((line != null) && ((limit == 0) || (result.size() < limit))) {
			result.add(line);
			if (terminatingPattern != null) {
				Matcher matcher = pattern.matcher(line);
				if (matcher.find()) {
					break;
				}
			}
			line = br.readLine();
		}

		return result;
	}

	/**
	 * 
	 * Read lines from process output. Addidionaly reading cannot last longer
	 * than specified time.
	 * 
	 * @param stream
	 *            process output stream.
	 * @param terminatingPattern
	 *            reading is stopped when the pattern is found.
	 * @param limit
	 *            limit of lines to read.
	 * @param timeout
	 *            time to interrupt, in miliseconds.
	 * @return list of Strings not containing pattern, list not longer than
	 *         specified limit.
	 * @throws IOException
	 *             if any IO error occurs.
	 * @throws InterruptedIOException
	 *             in the case the timeout has been reached.
	 */
	public static List<String> readLines(InputStream stream,
			String terminatingPattern, int limit, long timeout)
			throws IOException, InterruptedIOException {
		TimeoutKeeper keeper = null;
		if (timeout > 0) {
			keeper = new TimeoutKeeper(timeout);
			keeper.start();
		}
		List<String> result = readLines(stream, terminatingPattern, limit);
		if (timeout > 0) {
			keeper.stop();
		}
		return result;
	}
}
